﻿using Ldt.DataEngine.RuleAssemble;
using LdtJudge.DataEngine.Common;
using LdtJudge.DataEngine.Common.CommHelp;
using LdtJudge.DataEngine.Common.StringAssemble;
using LdtJudge.DataEngine.Common.XmlUtility;
using LdtJudge.DataEngine.Data;
using LdtJudge.DataEngine.DataBaseStores;
using LdtJudge.DataEngine.Model.DataModel.SysCommon;
using LdtJudge.DataEngine.Model.DataModel.SystemtableModel;
using LdtJudge.DataEngine.Model.ElmentModel;
using LdtJudge.DataEngine.Model.XMLConfigModel.DataStores;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
using LdtJudge.DataEngine.DataBaseStores.Cached;
using System.IO;
using LdtJudge.DataEngine.CallInterface.ConfiCenter;
using Ldt.InformationUnit.Common;
using Newtonsoft.Json;
using LdtJudge.DataEngine.Model.XMLConfigModel.SituationPloModel;
using LdtJudge.DataEngine.Model.XMLConfigModel.CircumsatanModel;
using Microsoft.Extensions.Configuration;
using LdtDataEngin.ModuleDetail.AnalysisModule.CaseCauseBaseInfoExtr;

namespace LdtDataEngin.ModuleDetail.BaseModule
{
    /// <summary>
    /// 情形情节基础类
    /// </summary>
    public abstract class SituationPlotBaseClass
    {
        /// <summary>
        /// 上下文
        /// </summary>
        public DataContext dataContext { get; set; }

        /// <summary>
        /// 系统查询
        /// </summary>
        public GetSysCaseCause dALSYS_CaseCause = new GetSysCaseCause();

        public List<KeyWord> KeyWords = new List<KeyWord> {
            new KeyWord{ code="suitpart",content="事实与指控一致" }
        };

        /// <summary>
        ///通用情形情节匹配
        /// </summary>
        /// <param name="CauseID">案由ID</param>
        /// <param name="IsDevelopSchedule">该状态用来判断是否进行规则匹配，而不是RuleItem匹配</param>
        /// <param name="MatchText">内容</param>
        /// <param name="commElement">条件对象</param>
        /// <param name="affirmType">认定意见结果</param>
        /// <param name="district">地域</param>
        /// <returns></returns>
        public abstract List<CommonPlotorSituation> MatchValueID(string CauseID, bool IsDevelopSchedule,
            string MatchText, CommElementRegexCode commElement, string affirmType, string district, string isml);

        /// <summary>
        /// 通过机器识别结果匹配情形情节
        /// </summary>
        /// <param name="mlCaseType">机器学习配置</param>
        /// <param name="orgContents">拆分后的语句</param>
        /// <param name="unMatchText">原文</param>
        /// <returns></returns>
        public List<CommonPlotorSituation> MatchListByMachLearn(SituationPlotMLCaseType mlCaseType, string ccid, List<SentenceModel> sentences, int matchType, out List<SentenceModel> unMatchSentences)
        {
            List<CommonPlotorSituation> models = new List<CommonPlotorSituation>();
            List<CommonPlotorSituation> matchLearnModels = new List<CommonPlotorSituation>();
            string regOrgText = string.Empty;
            unMatchSentences = sentences;
            if (sentences != null && sentences.Any())
            {
                List<SentenceModel> regSentence = new List<SentenceModel>();
                regSentence.AddRange(sentences);
                foreach (var sentenceItem in sentences)
                {
                    if (!string.IsNullOrWhiteSpace(sentenceItem.SentenceContent))
                    {
                        List<SYS_CaseCause> causes = new List<SYS_CaseCause>();
                        var recognition = mlCaseType.Recognitions.FirstOrDefault(x => x.MatchType == matchType);
                        if (recognition != null)
                        {
                            //机器学习编码集合
                            List<string> machCodes = new List<string>();
                            var commonCode = recognition.CommonCode;
                            //获取通用情节机器学习编码
                            if (!string.IsNullOrWhiteSpace(commonCode))
                            {
                                var commonMachCodes = commonCode.Split(',');
                                foreach (var codeItem in commonMachCodes)
                                {
                                    if (!string.IsNullOrWhiteSpace(codeItem))
                                        machCodes.Add(codeItem);
                                }
                            }
                            //获取个罪机器学习编码
                            var causeRecogns = recognition.Causes;
                            if (causeRecogns != null && recognition.Causes.Any())
                            {
                                var causeRecogn = causeRecogns.FirstOrDefault(x => x.Value.Contains(ccid));
                                if (causeRecogn != null)
                                {
                                    var mlCode = causeRecogn.mlcode;
                                    if (!string.IsNullOrWhiteSpace(mlCode))
                                    {
                                        var causeMachCodes = mlCode.Split(',');
                                        foreach (var codeItem in causeMachCodes)
                                        {
                                            if (!string.IsNullOrWhiteSpace(codeItem))
                                                machCodes.Add(codeItem);
                                        }
                                    }
                                }
                            }
                            if (machCodes != null && machCodes.Any())
                            {
                                foreach (var item in machCodes)
                                {
                                    //调用机器学习接口获取情形、情节数据
                                    var machModels = GetCausesByMachineLearn(sentenceItem.SentenceContent, item, matchType.ToString());
                                    if (machModels != null && machModels.Any())
                                        causes.AddRange(machModels);
                                }
                            }

                        }
                        if (causes.Any())
                        {
                            causes = causes.Distinct().ToList();
                            var matchSuccess = LoopExtractMatchLearn(sentenceItem, causes, ref matchLearnModels);
                            if (matchSuccess)
                            {
                                models.AddRange(matchLearnModels);
                                regSentence.Remove(sentenceItem);
                            }
                        }
                    }
                }
                unMatchSentences = regSentence;
            }

            return models;
        }

        public List<CommonPlotorSituation> MatchListByMachLearn(SituationPlotMLCaseType mlCaseType, string ccid, List<string> orgList, int matchType)
        {
            CaseCauseExtract caseCauseExtract = new CaseCauseExtract(null, null);

            List<CommonPlotorSituation> matchLearnModels = new List<CommonPlotorSituation>();
            //匹配结果
            List<CommonPlotorSituation> models = new List<CommonPlotorSituation>();
            //
            var recognition = mlCaseType.Recognitions.FirstOrDefault(x => x.MatchType == matchType);

            if (recognition != null)
            {
                var causemodel = recognition.Causes.FirstOrDefault(a => a.Value == ccid);
                List<string> mlcodeList = new List<string>();
                if (causemodel.mlcode.IndexOf(',') > -1)
                {
                    foreach (string code in causemodel.mlcode.Split(','))
                    {
                        mlcodeList.Add(code);
                    }
                }
                else
                {
                    mlcodeList.Add(causemodel.mlcode);
                }

                if (mlcodeList.Count > 0)
                {
                    foreach (string mlcode in mlcodeList)
                    {
                        foreach (string org in orgList)
                        {
                            dataContext.InteractiveShow.LogShow("违法行为开始调用机器学习，原文：" + org + "模型名称：" + mlcode);
                            List<CaseCauseModel> caseCauseModels = caseCauseExtract.GetCausesByMachineLearn(org,mlcode);
                            if (caseCauseModels.Any())
                            {
                                caseCauseModels = caseCauseModels.Distinct().ToList();
                                var matchSuccess = LoopExtractMatchLearn(org,"3", caseCauseModels, ref matchLearnModels);
                                dataContext.InteractiveShow.LogShow("违法行为开始调用机器学习返回值" + JsonConvert.SerializeObject(matchLearnModels));

                                if (matchSuccess)
                                {
                                    models.AddRange(matchLearnModels);
                                }
                            }
                        }

                    }
                }
            }
            return models;
        }

        /// <summary>
        /// 进行将输入的内容进行匹配是否能够匹配上当前的CC_ID 
        /// </summary>
        /// <param name="MatchText">文本内容</param>
        /// <param name="CC_ID">节点ID</param>
        /// <param name="ExpressSourceWhere">节点的条件</param>
        /// <returns>string</returns>
        private string MatchValueCommon(string MatchText, string CC_ID, CommElementRegexCode ExpressSourceWhere)
        {
            if (ExpressSourceWhere != null)
            {
                IList<MSYS_Express_Source> MSourceArr = null;
                MSourceArr = GetMSYS_Express_Sources(CC_ID, ExpressSourceWhere);

                ///当前规则数据集合，应该只有一条
                foreach (MSYS_Express_Source msource in MSourceArr)
                {
                    if (!string.IsNullOrWhiteSpace(msource.CC_RegexInfoCode))
                    {
                        ///正则编号
                        ExpressSourceWhere.RegexCode = msource.CC_RegexInfoCode;
                        Stopwatch swtext1 = new Stopwatch();
                        swtext1.Start();

                        string value = RuleParseClass.GetParseValue(msource.CC_RegexInfoCode, MatchText);
                        swtext1.Stop();
                        WriteLog("正则编号：" + msource.CC_RegexInfoCode + ",原文" + MatchText + "分析时长" + swtext1.ElapsedMilliseconds.ToString("0") + "毫秒", "\\log1\\log.txt", false);
                        if (string.IsNullOrWhiteSpace(value))
                        {
                            continue;
                        }

                        return value;
                    }
                }
            }

            return string.Empty;
        }
        private static object obj = new object();
        /// <summary>
        /// 将日志写入text
        /// </summary>
        /// <param name="content">内容</param>
        /// <param name="fileRelativePath">路径</param>
        /// <param name="tagDateTime">是否加时间分割线</param>
        public static void WriteLog(string content, string fileRelativePath, bool tagDateTime)
        {
            //lock (obj)
            //{
            //    string filePath = AppDomain.CurrentDomain.BaseDirectory + "\\" + fileRelativePath;
            //    string filefolder = AppDomain.CurrentDomain.BaseDirectory + "\\Log";
            //    if (!Directory.Exists(filefolder))
            //        Directory.CreateDirectory(filefolder);

            //    if (!File.Exists(filePath))
            //        File.Create(filePath).Close();

            //    StreamWriter sw = new StreamWriter(filePath, true);
            //    if (tagDateTime)
            //    {
            //        sw.WriteLine("\r\n" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "----------------------------");
            //    }
            //    sw.WriteLine(content);
            //    sw.WriteLine("\r\n");
            //    sw.Close();
            //}
        }

        /// <summary>
        /// 进行将输入的内容进行匹配是否能够匹配上当前的CC_ID 
        /// </summary>
        /// <param name="MatchText">文本内容</param>
        /// <param name="CC_ID">节点ID</param>
        /// <param name="ExpressSourceWhere">节点的条件</param>
        /// <returns>List<string></returns>
        public List<string> MatchListValueCommon(string MatchText, string CC_ID, CommElementRegexCode ExpressSourceWhere)
        {
            Stopwatch swtext = new Stopwatch();
            swtext.Start();
            List<string> ResultValueList = new List<string>();
            if (ExpressSourceWhere != null)
            {
                IList<MSYS_Express_Source> MSourceArr = null;
                MSourceArr = GetMSYS_Express_Sources(CC_ID, ExpressSourceWhere);

                ///当前规则数据集合，应该只有一条
                foreach (MSYS_Express_Source msource in MSourceArr)
                {
                    if (!string.IsNullOrWhiteSpace(msource.CC_RegexInfoCode))
                    {
                        ///正则编号
                        ExpressSourceWhere.RegexCode = msource.CC_RegexInfoCode;

                        var values = RuleParseClass.GetParseRegCodeList(msource.CC_RegexInfoCode, MatchText);

                        if (values?.Count > 0)
                        {
                            ResultValueList.AddRange(values);
                            ResultValueList.Distinct();
                        }
                        swtext.Stop();
                        RuleParseClass.WriteContentLog("获取正则结果，用时为：" + swtext.ElapsedMilliseconds + "毫秒" + "结果：" + JsonConvert.SerializeObject(values));

                        return ResultValueList;
                    }
                }
            }

            return ResultValueList;
        }

        /// <summary>
        /// 根据CCID与条件获取SYS_Express_Sources表配置信息
        /// </summary>
        /// <param name="CC_ID">节点CCID</param>
        /// <param name="ExpressSourceWhere">配置条件</param>
        /// <returns>匹配的SYS_Express_Sources表信息</returns>
        private IList<MSYS_Express_Source> GetMSYS_Express_Sources(string CC_ID, CommElementRegexCode ExpressSourceWhere)
        {
            IList<MSYS_Express_Source> MSourceArr;
            if (dataContext != null && dataContext.DataLayerAns.dicTable.ContainsKey("MSYS_Express_Source"))
            {
                Stopwatch s1 = new Stopwatch();
                s1.Start();

                var initial = MsysExpressSourceCached.Copy_Hash(MsysExpressSourceCached.EsIdSt);

                if (!string.IsNullOrWhiteSpace(CC_ID))
                {
                    initial = MsysExpressSourceCached.HashSet_String_Intersection(initial,
                        MsysExpressSourceCached.CcIdHt[CC_ID]);
                }

                if (!string.IsNullOrWhiteSpace(ExpressSourceWhere.PargarphCode))
                {
                    initial = MsysExpressSourceCached.HashSet_String_Intersection(initial,
                        MsysExpressSourceCached.SourceParagraphIdHt[ExpressSourceWhere.PargarphCode.ToLower()]);
                }

                if (!string.IsNullOrWhiteSpace(ExpressSourceWhere.SourceCode))
                {
                    initial = MsysExpressSourceCached.HashSet_String_Intersection(initial,
                        MsysExpressSourceCached.SourceIdHt[ExpressSourceWhere.SourceCode]);
                }

                if (ExpressSourceWhere.TextType > 0)
                {
                    initial = MsysExpressSourceCached.HashSet_String_Intersection(initial,
                        MsysExpressSourceCached.SourceTextTypeHt[ExpressSourceWhere.TextType.ToString()]);
                }

                if (ExpressSourceWhere.Purpose == ExtractType.cailiangqingjie)
                {
                    initial = MsysExpressSourceCached.HashSet_String_Intersection(initial,
                        MsysExpressSourceCached.EsPurposeHt["c97b8bb7-7a13-443f-ba2f-0b286b9d0e46"]);
                }
                else
                {
                    initial = MsysExpressSourceCached.HashSet_String_Intersection(initial,
                        MsysExpressSourceCached.AmCodeHt[((int)ExpressSourceWhere.Purpose).ToString()]);
                }

                MSourceArr = MsysExpressSourceCached.Restore(initial);
                s1.Stop();
                RuleParseClass.WriteContentLog("通过缓存取SYS_Express_Source数据，用时为：" + s1.ElapsedMilliseconds + "毫秒");

            }
            else
            {
                Stopwatch s1 = new Stopwatch();
                s1.Start();
                string sqlwhere = "  1=1 ";
                if (!string.IsNullOrWhiteSpace(CC_ID))
                {
                    //节点的ID
                    sqlwhere += " and a.CC_ID = '" + CC_ID + "' ";
                }

                if (!string.IsNullOrWhiteSpace(ExpressSourceWhere.SourceCode))
                {
                    //文书编号
                    sqlwhere += " and a.Source_ID like '%" + ExpressSourceWhere.SourceCode + "%'";
                }

                if (!string.IsNullOrWhiteSpace(ExpressSourceWhere.PargarphCode))
                {
                    //逻辑段编号
                    string where = string.IsNullOrWhiteSpace(ExpressSourceWhere.PargarphWhere)
                        ? "="
                        : ExpressSourceWhere.PargarphWhere;
                    sqlwhere += " and lower(a.Source_ParagraphID) " + where + "'" +
                                ExpressSourceWhere.PargarphCode.ToLower() + "'";
                }

                if (ExpressSourceWhere.TextType > 0)
                {
                    //文本类型
                    sqlwhere += " and Source_TextType = " + ExpressSourceWhere.TextType;
                }

                //用途
                if (ExpressSourceWhere.Purpose == ExtractType.cailiangqingjie)
                {
                    sqlwhere += " and ES_Purpose =  'c97b8bb7-7a13-443f-ba2f-0b286b9d0e46 ' ";
                }
                else
                {
                    sqlwhere += " and AM_Code =  '" + (int)ExpressSourceWhere.Purpose + " ' ";
                }

                DALSYS_Express_Source dalRegexSource = new DALSYS_Express_Source();
                MSourceArr = dalRegexSource.GetListArrayWhere(sqlwhere);
                s1.Stop();
                RuleParseClass.WriteContentLog("通过数据库取SYS_Express_Source数据，用时为：" + s1.ElapsedMilliseconds + "毫秒");
            }

            return MSourceArr;
        }

        /// <summary>
        /// 进行匹配案由当中配置的RuleItem
        /// </summary>
        /// <param name="RootNodeID">根节点ID</param>
        /// <param name="MatchText">原文</param>
        /// <param name="oTable">要匹配的表数据</param>
        /// <param name="parentCCID">CC_ID</param>
        /// <param name="commElement">条件</param>
        /// <param name="commonPlotorSituations">返回的对象</param>
        /// <returns></returns>
        public bool LoopExtractRuleItem(string RootNodeID, string MatchText, List<SYS_CaseCause> oTable,
            string parentCCID, CommElementRegexCode commElement, string affirmType, ref List<CommonPlotorSituation> commonPlotorSituations)
        {
            List<SYS_CaseCause> dataRows = oTable.Where(a => a.CC_ParentID == parentCCID).ToList();
            if (dataRows.Count == 0)
            {
                return false;
            }

            bool isExistsMatch = false; //默认不存在匹配
            foreach (SYS_CaseCause row in dataRows)
            {
                string PlotName = LdFormat.ObjectToString(row.CC_Name); //情节情形名称
                string PlotID = LdFormat.ObjectToString(row.CC_ID); //情节情形ID 
                string inferRuleItem = LdFormat.ObjectToString(row.RuleItem); //情节情形IRuleItem
                string po_type = LdFormat.ObjectToString(row.CC_NodeType); //情节情形类型 
                string cc_parentid = LdFormat.ObjectToString(row.CC_ParentID); //情节情形父级ID
                List<string> allparentid = new List<string>();
                if (!string.IsNullOrWhiteSpace(row.AllParentId))
                {
                    string allparentidStr = row.AllParentId.Replace(row.CC_ID, "").Trim(',').Trim();
                    allparentid = allparentidStr.Split(',').Where(x => !string.IsNullOrWhiteSpace(x)).ToList();
                }

                if (!string.IsNullOrWhiteSpace(inferRuleItem))
                {
                    bool flag = RuleParseClass.IsMatchKeyWordXML(MatchText, inferRuleItem); //判断是否符合规则
                    if (flag)
                    {
                        flag = LoopExtractRuleItem(RootNodeID, MatchText, oTable, PlotID, commElement, affirmType,
                            ref commonPlotorSituations);
                        if (!flag)
                        {
                            if (RootNodeID != parentCCID)
                            {
                                CommonPlotorSituation MPlot = new CommonPlotorSituation();
                                MPlot.Common_name = PlotName;
                                MPlot.Common_id = PlotID;
                                MPlot.Common_typeid = po_type;
                                MPlot.Common_originalText = MatchText;
                                MPlot.Common_parentid = allparentid;
                                MPlot.Common_affirm = affirmType;
                                commonPlotorSituations.Add(MPlot);
                            }
                        }

                        isExistsMatch = true; //当前层次，存在匹配。
                    }
                }
                else if (RootNodeID == parentCCID)
                {
                    ///2018-11-20 ljx 添加关于如果当前的案由未开发，则情形情节的匹配规则为RuleItem类型，但是该匹配关系还不能进行匹配案由下的第一子级。
                    LoopExtractRuleItem(RootNodeID, MatchText, oTable, PlotID, commElement, affirmType, ref commonPlotorSituations);
                }
            }

            return isExistsMatch;
        }

        /// <summary>
        /// 转换出配置实体
        /// </summary>
        /// <param name="cofing">配置文件</param>
        public ParagraphModel GetConfigModel(string cofing,string caseType,string docType,string paragraphCode)
        {
            DyData_Analysis dataLayerAns = new DyData_Analysis();
            dataLayerAns.CaseType = caseType;
            dataLayerAns.SourceCode = docType;
            dataContext = new DataContext(null, dataLayerAns,null,null);
           


            CauseCircumsatanModel causeCircumsatanModel= XmlUtility.DeserializeToObject<CauseCircumsatanModel>(cofing);
            var doctypemodel = causeCircumsatanModel.casetypeModelList.FirstOrDefault(a => a.Code.ToLower() == caseType.ToLower());
            if (doctypemodel!=null)
            {
                var crmodel = doctypemodel.docTypeList.FirstOrDefault(a => a.Code.ToLower() == docType.ToLower());
                if (crmodel!=null)
                {
                    ParagraphModel paragraphmodel = crmodel.paragraphModelList.FirstOrDefault(a => a.Code.ToLower() == paragraphCode.ToLower());
                    return paragraphmodel;
                }
            }
            
           
            return  null;
        }

        /// <summary>
        /// 通用方法进行递归匹配数据
        /// </summary>
        /// <param name="RootNodeID">根节点ID</param>
        /// <param name="MatchText">原文</param>
        /// <param name="oTable">要匹配的表数据</param>
        /// <param name="parentCCID">CC_ID</param>
        /// <param name="commElement">条件</param>
        /// <param name="commonPlotorSituations">返回的对象</param>
        /// <returns></returns>
        public bool LoopExtractPlotCommon(string RootNodeID, string MatchText, List<SYS_CaseCause> oTable,
            string parentCCID, CommElementRegexCode commElement, ref List<CommonPlotorSituation> commonPlotorSituations)
        {
            List<SYS_CaseCause> dataRows = oTable.Where(a => a.CC_ParentID == parentCCID).ToList();
            if (dataRows.Count == 0)
            {
                return false;
            }
            RuleParseClass.WriteContentLog("情节情形父级ccid:" + parentCCID + " 下级节点数量:" + dataRows.Count);

            bool isExistsMatch = false; //默认不存在匹配
            foreach (SYS_CaseCause row in dataRows)
            {
                Stopwatch swtext1 = new Stopwatch();
                swtext1.Start();

                string PlotName = LdFormat.ObjectToString(row.CC_Name); //情节情形名称
                string PlotID = LdFormat.ObjectToString(row.CC_ID); //情节情形ID 
                string po_type = LdFormat.ObjectToString(row.CC_NodeType); //情节情形类型 
                string cc_parentid = LdFormat.ObjectToString(row.CC_ParentID); //情节情形父级ID
                List<string> allparentid = new List<string>();
                if (!string.IsNullOrWhiteSpace(row.AllParentId))
                {
                    string allparentidStr = row.AllParentId.Replace(row.CC_ID, "").Trim(',').Trim();
                    allparentid = allparentidStr.Split(',').Where(x => !string.IsNullOrWhiteSpace(x)).ToList();
                }

                if (RootNodeID == cc_parentid && RootNodeID != "1000")
                {
                    ///如果当前的节点是案由的直接子级，需要进行获取匹配内容 1000表示刑事案由节点
                    List<string> oMatchs = MatchListValueCommon(MatchText, PlotID, commElement);
                    if (dataContext != null)
                    {
                        dataContext.InteractiveShow.LogShow($"  当前案由ID:{RootNodeID} 的直接子级[{PlotID}-{PlotName}]匹配到的原文值为：");
                    }

                    for (int i = 0; i < oMatchs.Count; i++)
                    {
                        string oMatch = oMatchs[i];
                        if (dataContext != null)
                            dataContext.InteractiveShow.LogShow($"      当前的第{i + 1}的原文内容为：" + oMatch);
                        if (!string.IsNullOrWhiteSpace(oMatch))
                        {
                            LoopExtractPlotCommon(RootNodeID, oMatch, oTable, PlotID, commElement,
                                ref commonPlotorSituations);
                        }
                    }
                }
                else
                {
                    string oMatch = MatchValueCommon(MatchText, PlotID, commElement);
                    if (!string.IsNullOrWhiteSpace(oMatch))
                    {
                        bool isExistsSonMatch = LoopExtractPlotCommon(RootNodeID, MatchText, oTable, PlotID,
                            commElement, ref commonPlotorSituations);
                        if (!isExistsSonMatch)
                        {
                            if (RootNodeID != parentCCID)
                            {
                                if (RootNodeID == "1000")
                                {
                                    ///表示为公共的情形信息
                                    switch (po_type)
                                    {
                                        case "5":
                                            po_type = "a1";
                                            break;
                                        case "6":
                                            po_type = "a2";
                                            break;
                                    }
                                }

                                switch (po_type)
                                {
                                    case "5":
                                        po_type = "a1";
                                        break;
                                    case "6":
                                        po_type = "a2";
                                        break;
                                }

                                CommonPlotorSituation MPlot = new CommonPlotorSituation();
                                MPlot.Common_name = PlotName;
                                MPlot.Common_id = PlotID;
                                MPlot.Common_typeid = po_type;
                                MPlot.Common_originalText = oMatch;
                                MPlot.Mc_influencetypeid = row.MC_influenceTypeID;
                                MPlot.Common_parentid = allparentid;
                                commonPlotorSituations.Add(MPlot);
                            }
                        }

                        isExistsMatch = true; //当前层次，存在匹配。
                    }
                }

                swtext1.Stop();
                RuleParseClass.WriteContentLog("情节情形名称:" + PlotName + " ID:" + PlotID + "匹配用时为：" + swtext1.ElapsedMilliseconds + "毫秒");

            }

            return isExistsMatch;
        }

        /// <summary>
        /// 通用方法进行递归匹配数据
        /// </summary>
        /// <param name="RootNodeID">根节点ID</param>
        /// <param name="MatchText">原文</param>
        /// <param name="oTable">要匹配的表数据</param>
        /// <param name="parentCCID">CC_ID</param>
        /// <param name="commElement">条件</param>
        /// <param name="affirm">认定状态</param>
        /// <param name="commonPlotorSituations">返回的对象</param>
        /// <returns></returns>
        public bool LoopExtractPlotCommon(string RootNodeID, string MatchText, List<SYS_CaseCause> oTable,
            string parentCCID, CommElementRegexCode commElement, string affirm, ref List<CommonPlotorSituation> commonPlotorSituations)
        {
            List<SYS_CaseCause> dataRows = oTable.Where(a => a.CC_ParentID == parentCCID).ToList();
            if (dataRows.Count == 0)
            {
                return false;
            }
            RuleParseClass.WriteContentLog("情节父级ID:" + parentCCID + " 子节点数量:" + dataRows.Count);

            bool isExistsMatch = false; //默认不存在匹配
            foreach (SYS_CaseCause row in dataRows)
            {
                Stopwatch swtext1 = new Stopwatch();
                swtext1.Start();

                string PlotName = LdFormat.ObjectToString(row.CC_Name); //情节情形名称
                string PlotID = LdFormat.ObjectToString(row.CC_ID); //情节情形ID 
                string po_type = LdFormat.ObjectToString(row.CC_NodeType); //情节情形类型 
                string cc_parentid = LdFormat.ObjectToString(row.CC_ParentID); //情节情形父级ID
                List<string> allparentid = new List<string>();
                if (!string.IsNullOrWhiteSpace(row.AllParentId))
                {
                    string allparentidStr = row.AllParentId.Replace(row.CC_ID, "").Trim(',').Trim();
                    allparentid = allparentidStr.Split(',',StringSplitOptions.RemoveEmptyEntries).ToList();
                }

                if (RootNodeID == cc_parentid && RootNodeID != "1000")
                {
                    ///如果当前的节点是案由的直接子级，需要进行获取匹配内容 1000表示刑事案由节点
                    List<string> oMatchs = MatchListValueCommon(MatchText, PlotID, commElement);
                    if (dataContext != null)
                    {
                        dataContext.InteractiveShow?.LogShow($"  当前案由ID:{RootNodeID} 的直接子级[{PlotID}-{PlotName}]匹配到的原文值为：");
                    }

                    for (int i = 0; i < oMatchs.Count; i++)
                    {
                        string oMatch = oMatchs[i];
                        if (dataContext != null)
                            dataContext.InteractiveShow?.LogShow($"      当前的第{i + 1}的原文内容为：" + oMatch);
                        if (!string.IsNullOrWhiteSpace(oMatch))
                        {
                            LoopExtractPlotCommon(RootNodeID, oMatch, oTable, PlotID, commElement, affirm,
                                ref commonPlotorSituations);
                        }
                    }
                }
                else
                {
                    string oMatch = MatchValueCommon(MatchText, PlotID, commElement);
                    if (!string.IsNullOrWhiteSpace(oMatch))
                    {
                        bool isExistsSonMatch = LoopExtractPlotCommon(RootNodeID, MatchText, oTable, PlotID,
                            commElement, affirm, ref commonPlotorSituations);
                        if (!isExistsSonMatch)
                        {
                            if (RootNodeID != parentCCID)
                            {
                                if (RootNodeID == "1000")
                                {
                                    ///表示为公共的情形信息
                                    switch (po_type)
                                    {
                                        case "5":
                                            po_type = "a1";
                                            break;
                                        case "6":
                                            po_type = "a2";
                                            break;
                                    }
                                }

                                switch (po_type)
                                {
                                    case "5":
                                        po_type = "a1";
                                        break;
                                    case "6":
                                        po_type = "a2";
                                        break;
                                }

                                CommonPlotorSituation MPlot = new CommonPlotorSituation();
                                MPlot.Common_name = PlotName;
                                MPlot.Common_id = PlotID;
                                MPlot.Common_typeid = po_type;
                                MPlot.Common_originalText = oMatch;
                                MPlot.Mc_influencetypeid = row.MC_influenceTypeID;
                                MPlot.Common_parentid = allparentid;
                                MPlot.Common_affirm = affirm;
                                commonPlotorSituations.Add(MPlot);
                            }
                        }

                        isExistsMatch = true; //当前层次，存在匹配。
                    }
                }

                swtext1.Stop();
                RuleParseClass.WriteContentLog("情节情形名称:"+ PlotName+" ID:"+ PlotID + "匹配用时为：" + swtext1.Elapsed.TotalMilliseconds + "毫秒");

            }

            return isExistsMatch;
        }

        /// <summary>
        /// 机器学习匹配数据
        /// </summary>
        /// <param name="matchText">原文</param>
        /// <param name="causes">案由</param>
        /// <param name="commonPlotorSituations">返回对象</param>
        /// <returns></returns>
        public bool LoopExtractMatchLearn(SentenceModel sentenceModel, List<SYS_CaseCause> causes, ref List<CommonPlotorSituation> commonPlotorSituations)
        {
            if (causes.Count == 0)
            {
                return false;
            }
            bool isExistsMatch = false; //默认不存在匹配
            foreach (SYS_CaseCause row in causes)
            {
                string commonName = LdFormat.ObjectToString(row.CC_Name); //情节情形名称
                string commonId = LdFormat.ObjectToString(row.CC_ID); //情形/情节ID 
                string common_type = LdFormat.ObjectToString(row.CC_NodeType); //情节情形类型 
                string cc_parentid = LdFormat.ObjectToString(row.CC_ParentID); //情节情形父级ID
                List<string> allparentid = new List<string>();
                if (!string.IsNullOrWhiteSpace(row.AllParentId))
                {
                    string allparentidStr = row.AllParentId.Replace(row.CC_ID, "").Trim(',').Trim();
                    allparentid = allparentidStr.Split(',').Where(x => !string.IsNullOrWhiteSpace(x)).ToList();
                }
                CommonPlotorSituation commonData = new CommonPlotorSituation();
                commonData.Common_name = commonName;
                commonData.Common_id = commonId;
                commonData.Common_typeid = common_type;
                commonData.Common_originalText = sentenceModel.SentenceContent;
                commonData.Common_parentid = allparentid;
                commonData.Common_affirm = sentenceModel.SentenceType;
                commonPlotorSituations.Add(commonData);
                isExistsMatch = true; //当前层次，存在匹配。
            }
            return isExistsMatch;
        }

        public bool LoopExtractMatchLearn(string orgvalue,string type, List<LdtJudge.DataEngine.Model.DataModel.SysCommon.CaseCauseModel> causes, ref List<CommonPlotorSituation> commonPlotorSituations)
        {
            if (causes.Count == 0)
            {
                return false;
            }
            bool isExistsMatch = false; //默认不存在匹配
            foreach (LdtJudge.DataEngine.Model.DataModel.SysCommon.CaseCauseModel row in causes)
            {
                string commonName = LdFormat.ObjectToString(row.CC_Name); //情节情形名称
                string commonId = LdFormat.ObjectToString(row.CC_ID); //情形/情节ID 
                string common_type = LdFormat.ObjectToString(row.CC_NodeType); //情节情形类型 
                string cc_parentid = LdFormat.ObjectToString(row.CC_ParentID); //情节情形父级ID
                List<string> allparentid = new List<string>();
                if (!string.IsNullOrWhiteSpace(row.AllParentId))
                {
                    string allparentidStr = row.AllParentId.Replace(row.CC_ID, "").Trim(',').Trim();
                    allparentid = allparentidStr.Split(',').Where(x => !string.IsNullOrWhiteSpace(x)).ToList();
                }
                CommonPlotorSituation commonData = new CommonPlotorSituation();
                commonData.Common_name = commonName;
                commonData.Common_id = commonId;
                commonData.Common_typeid = common_type;
                commonData.Common_originalText = orgvalue;
                commonData.Common_parentid = allparentid;
                commonData.Common_affirm = type;
                commonPlotorSituations.Add(commonData);
                isExistsMatch = true; //当前层次，存在匹配。
            }
            return isExistsMatch;
        }


        //protected List<string> Get_ParagraphOriginText(string PT_SourceParagraph)
        //{
        //    string valueText = "";
        //    List<string> origList = new List<string>();
        //    string[] paragraph = PT_SourceParagraph.Split(',');
        //    foreach (string value in paragraph)
        //    {
        //        List<SD_ParagraphTXTModel> sd_ParagraphTXTList = dataLayerStores.AnalysisParameter.sourceDossierInfo.SD_ParagraphTXTList.Where(a => a.SDP_ParagraphCode == value).ToList();
        //        if (sd_ParagraphTXTList.Count > 0)
        //        {
        //            if (sd_ParagraphTXTList.Count > 1)
        //            {
        //                foreach (var codevalue in sd_ParagraphTXTList)
        //                {
        //                    if (codevalue.SDP_Content.Trim() != "")
        //                    {
        //                        valueText += "\r\n" + codevalue.SDP_Content;
        //                    }
        //                }
        //            }
        //            else
        //            {
        //                if (sd_ParagraphTXTList.Count > 0)
        //                {
        //                    valueText += sd_ParagraphTXTList[0].SDP_Content;
        //                }
        //            }
        //        }
        //    }
        //    origList.Add(valueText);
        //    return origList;
        //}


        /// <summary>
        /// 补全Xpath路径值
        /// </summary>
        /// <param name="dataModelCaseElmentList">实体集合</param>
        /// <param name="path">路径集合</param>
        /// <returns></returns>
        public string CaseNodeUpdate(List<DataModel> dataModelCaseElmentList, string path)
        {
            DataModel dataModel = XmlUtility.ConditionFirstOrDefaultDataModel(dataModelCaseElmentList, "", path);
            if (dataModel == null)
            {
                string xpath = "";
                List<string> pathList = path.Split("/").ToList();
                pathList.RemoveAt(pathList.Count - 1);
                foreach (string nodename in pathList)
                {
                    if (xpath == "")
                    {
                        xpath = xpath + nodename;
                    }
                    else
                    {
                        xpath = xpath + "/" + nodename;
                    }
                }

                string uid = "";
                if (XmlUtility.ConditionFirstOrDefaultDataModel(dataModelCaseElmentList, "", xpath) == null)
                {
                    uid = CaseNodeUpdate(dataModelCaseElmentList, xpath);
                }
                else
                {
                    uid = XmlUtility.ConditionFirstOrDefaultDataModel(dataModelCaseElmentList, "", xpath).ID;
                }

                if (string.IsNullOrEmpty(uid))
                {
                    return "";
                }

                string xmlpath = path;
                Regex r = new Regex(@"\[[^,，。;；/]*?\]");
                MatchCollection mc = r.Matches(xmlpath);
                for (int i = 0; i < mc.Count; i++)
                {
                    xmlpath = xmlpath.Replace(mc[i].Value, "");
                }

                DataModel dataModelCauseName = new DataModel();
                dataModelCauseName.ID = Snowflake.Instance().GetId().ToString();
                dataModelCauseName.XmlPath = path;
                dataModelCauseName.sourceData = new SourceData();
                dataModelCauseName.ParentId = uid;
                dataModelCauseName.sourceData.sourceList = new List<Source>();
                Source source = new Source();
                source.SourceCode = dataContext.DataLayerAns.SourceCode;
                source.IsCheck = "1";
                dataModelCauseName.sourceData.sourceList.Add(source);
                dataModelCaseElmentList.Add(dataModelCauseName);

                return dataModelCauseName.ID;
            }
            else
            {
                return dataModel.ID;
            }
        }

        /// <summary>
        /// 通过机器学习获取案由数据
        /// </summary>
        /// <param name="originalText">原文</param>
        /// <param name="matchCode">机器学习编号</param>
        /// <param name="matchType">机器学习类型 1.情形 2.情节</param>
        /// <returns></returns>
        public List<SYS_CaseCause> GetCausesByMachineLearn(string originalText, string matchCode, string matchType)
        {
            //Dictionary<object, string> dicML = new Dictionary<object, string>();
            string matchTypeDesc = matchType == "1" ? "情形" : "情节";
            List<SYS_CaseCause> reList = new List<SYS_CaseCause>();
            string recogService = ConfigRetrieval.GetConfigRetrieval.GetAppSettingString("causedistinguish");
            string url = $"{recogService}/CaseCauseValid/CaseCauseValid/GetVerification";
            var recogParam = new
            {
                content = originalText,
                modelId = matchCode
            };
            string recogCauses = string.Empty;
            string recogReturn = string.Empty;
            if (dataContext.dicML.ContainsKey(recogParam))
            {
                recogReturn = dataContext.dicML[recogParam];
                dataContext.InteractiveShow?.LogShow("机器学习缓存返回：" + recogReturn);
            }
            else
            {
                recogReturn = WebUtil.DoPostNew(url, recogParam);
                dataContext.dicML.Add(recogParam, recogReturn);
            }
            dynamic recogResult = null;
            if (!string.IsNullOrWhiteSpace(recogReturn))
                recogResult = JsonConvert.DeserializeObject<dynamic>(recogReturn);
            if (recogResult != null && recogResult?.code == "1")
            {
                if (matchType == "1")
                    recogCauses = recogResult.body?.qingxing;
                else if (matchType == "2")
                {
                    recogCauses = $"{recogResult.body?.qingxing},{recogResult.body?.qingjie}";
                }

            }
            //调用案由识别服务

            dataContext.InteractiveShow?.LogShow($"调用机器学习【{url}】提取{matchTypeDesc},参数:{JsonConvert.SerializeObject(recogParam)},返回结果：{recogResult}");
            if (!string.IsNullOrWhiteSpace(recogCauses))
            {
                List<string> causeStrs = recogCauses.Split(",", StringSplitOptions.RemoveEmptyEntries).ToList();
                foreach (var cause in causeStrs)
                {
                    if (cause != "无结果")
                    {
                        SYS_CaseCause caseCause = null;
                        switch (matchType)
                        {
                            case "1"://情形
                                var ccid = cause.Split("_")[0];
                                caseCause = dALSYS_CaseCause.GetCauseModel(ccid);
                                break;
                            case "2": //情节
                                string ccName = string.Empty;
                                var causeSplits = cause.Split("_");
                                if (causeSplits.Length > 1)
                                    ccName = causeSplits[1];
                                if (!string.IsNullOrWhiteSpace(ccName))
                                    caseCause = dALSYS_CaseCause.GetPlotCauseByCCName(ccName, true);
                                break;
                            default:
                                break;
                        }
                        if (caseCause != null)
                            reList.Add(caseCause);
                    }
                }
            }
            return reList;
        }

        /// <summary>
        /// 对段落原文进行拆句
        /// </summary>
        /// <param name="paragraphText">段落原文</param>
        /// <param name="paragraphCode">段落编号</param>
        /// <param name="circumsatanModel">情形/情节配置</param>
        /// <param name="moduleType">模块类型 1.案由提取模块 2.情形/情节提取模块</param>
        /// <param name="isAccusation">是否指控段落</param>
        public List<SentenceModel> SentenceSplitting(string paragraphText, string paragraphCode, CircumsatanModel circumsatanModel, string moduleType, string ccid, bool isAccusation = false)
        {
            List<SentenceModel> sentences = new List<SentenceModel>();
            //如果段落原文为空，则通过段落编号从分析结果的段落集合中取原文
            if (string.IsNullOrWhiteSpace(paragraphText))
            {
                var paragraphInfo = dataContext.DataLayerAns.Duanluos.FirstOrDefault(x => x.Duanluobianhao.ToLower() == paragraphCode.ToLower());
                if (paragraphInfo != null && isAccusation)
                    paragraphText = paragraphInfo.Duanluoneirong;

            }
            if (circumsatanModel != null && circumsatanModel.casetypeModelList.Any())
            {
                //获取拆句正则
                var caseType = circumsatanModel.casetypeModelList.FirstOrDefault(x => x.Code.ToLower() == dataContext.DataLayerAns.CaseType.ToLower());
                if (caseType != null)
                {
                    if (!string.IsNullOrWhiteSpace(paragraphText) && !string.IsNullOrWhiteSpace(caseType.SentenceRegcode))
                    {
                        //步骤1.执行拆句正则
                        var splitDatas = RuleParseClass.GetParseRegCodeList(caseType.SentenceRegcode, paragraphText);
                        if (splitDatas != null && splitDatas.Any())
                        {
                            //获取否定句/认定句判断正则
                            DocType docType = null;
                            if (moduleType == "1")
                            {
                                var causeConfig = caseType.CirCasecauseList.FirstOrDefault(x => x.Code == ccid);
                                if (causeConfig != null)
                                    docType = causeConfig.docTypeList.FirstOrDefault(x => x.Code.ToLower() == dataContext.DataLayerAns.SourceCode.ToLower());
                            }
                            else if (moduleType == "2")
                            {
                                docType = caseType.docTypeList.FirstOrDefault(x => x.Code.ToLower() == dataContext.DataLayerAns.SourceCode.ToLower());
                            }
                            if (docType != null)
                            {
                                //认定句集合
                                List<string> affirmativeList = new List<string>();
                                foreach (var splitItem in splitDatas)
                                {
                                    if (!string.IsNullOrWhiteSpace(splitItem) && !string.IsNullOrWhiteSpace(docType.DenyRegCode))
                                    {
                                        //步骤2.否定句/认定句判断,通过正则执行完返回 true.否定句 false.认定句
                                        SentenceModel sentenceModel = new SentenceModel();
                                        sentenceModel.SentenceContent = splitItem;
                                        string denyResult = string.Empty;
                                        string denyResultRemark = string.Empty;
                                        Dictionary<string, List<string>> denyDic = RuleParseClass.RegularList(new List<string> { splitItem }, "", "", docType.DenyRegCode);
                                        if (denyDic != null && denyDic.Count > 0)
                                        {
                                            if (denyDic.ContainsKey("match"))
                                            {
                                                var denyReturnList = denyDic["match"];
                                                if (denyReturnList[0] == "1")
                                                {
                                                    denyResult = "0";//否定句
                                                    denyResultRemark = "否定句";
                                                }
                                                else if (denyReturnList[0] == "0")
                                                {
                                                    denyResult = "1";//认定句
                                                    denyResultRemark = "认定句";
                                                }
                                            }
                                        }
                                        dataContext.InteractiveShow?.LogShow($"拆分后语句【{splitItem}】通过正则编号【{docType.DenyRegCode}】执行否定句/认定句判断正则结果:【{denyResultRemark}】");
                                        sentenceModel.SentenceType = denyResult;
                                        if (denyResult == "1")
                                        {
                                            //添加到认定句集合中，执行步骤3执行关键词判定
                                            affirmativeList.Add(splitItem);
                                        }
                                        sentences.Add(sentenceModel);
                                    }
                                }

                                if (affirmativeList.Any())
                                {
                                    //获取关键词判定正则
                                    var paragraphConfig = docType.paragraphModelList.FirstOrDefault(x => x.Code.ToLower() == paragraphCode.ToLower());
                                    if (paragraphConfig != null && !string.IsNullOrWhiteSpace(paragraphConfig.DetermineRegCode))
                                    {
                                        //如果有认定句，则执行关键词判定
                                        foreach (var affirmativeItem in affirmativeList)
                                        {
                                            string affirmativeText = affirmativeItem;
                                            if (isAccusation)
                                            {
                                                affirmativeText = affirmativeItem.Replace("事实与指控一致", "")
                                                                             .Replace("驳回上诉，维持原判", "")
                                                                             .Replace("发回重审", "")
                                                                             .Replace("改判", "");
                                            }
                                            //步骤3.执行关键词判定
                                            var determineResult = RuleParseClass.GetParseRegCodeValue(paragraphConfig.DetermineRegCode, affirmativeText);
                                            if (!string.IsNullOrWhiteSpace(determineResult))
                                            {
                                                if (KeyWords.Any(x => x.content == determineResult))
                                                {
                                                    var keyWord = KeyWords.FirstOrDefault(x => x.content == determineResult);
                                                    string newParagraphCode = keyWord.code;
                                                    var determineDatas = SentenceSplitting("", newParagraphCode, circumsatanModel, moduleType, ccid, true);
                                                    if (determineDatas != null && determineDatas.Any())
                                                        sentences.AddRange(determineDatas);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return sentences;
        }

    }

    public class ForeignKey
    {
        public string Fk;
        public string Oringtext;
        public string Path;
        public string paragraphCode;
        public string fileid;
        public string nodename;
        public string type;
        public string isml;
    }

    /// <summary>
    /// 关键词
    /// </summary>
    public class KeyWord
    {
        /// <summary>
        /// 指向段落编号
        /// </summary>
        public string code { get; set; }

        //内容
        public string content { get; set; }
    }
}